package com.springboot.service.impl;

import java.math.BigDecimal;

import com.springboot.mapper.*;
import com.springboot.model.bo.BVirtualWalletBO;
import com.springboot.model.bo.VirtualWalletBO;
import com.springboot.model.po.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.springboot.constants.TransactionStatus;
import com.springboot.exceptions.InsufficientBalanceException;
import com.springboot.exceptions.InvalidAmountException;
import com.springboot.mapper.VirtualWalletMapper;
import com.springboot.mapper.VirtualWalletTransactionMapper;
import com.springboot.service.VirtualWalletService;

@Service
public class VirtualWalletServiceImpl implements VirtualWalletService {
	@Autowired
	private VirtualWalletMapper virtualWalletMapper;
	@Autowired
	private VirtualWalletTransactionMapper transactionMapper;
	@Autowired
	private BVirtualWalletMapper bvirtualWalletMapper;

	@Autowired
	private OrdersMapper ordersMapper;

	@Override
	public VirtualWalletBO getVirtualWalletByUserId(String userId) {
		VirtualWalletPO vpo = virtualWalletMapper.getVirtualWalletByUserId(userId);
		if(vpo == null) {
			return null;
		}else {
			VirtualWalletBO vbo = new VirtualWalletBO(1);
			vbo.setBalance(vpo.getBalance());
			vbo.setUserId(vpo.getUserId());
			vbo.setWalletId(vpo.getWalletId());
			return vbo;
		}
		
	}

	@Override
	public VirtualWalletBO getVirtualWallet(Integer walletId) {
		VirtualWalletPO vpo = virtualWalletMapper.getVirtualWallet(walletId);
		if(vpo == null) {
			return null;
		}else {
			VirtualWalletBO vbo = new VirtualWalletBO(1);
			vbo.setBalance(vpo.getBalance());
			vbo.setUserId(vpo.getUserId());
			vbo.setWalletId(vpo.getWalletId());
			return vbo;
		}
	}
	
	@Transactional
	@Override
	public BigDecimal getBalance(Integer walletId) {
		return virtualWalletMapper.getBalance(walletId);
	}

	//提现
	@Transactional
	@Override
	public int debit(Integer walletId, BigDecimal amount) {
		VirtualWalletPO wallet = virtualWalletMapper.getVirtualWallet(walletId);
		VirtualWalletBO vbo = new VirtualWalletBO(1);
		vbo.setBalance(wallet.getBalance());
		vbo.setUserId(wallet.getUserId());
		vbo.setWalletId(wallet.getWalletId());
		try {
			vbo.debit(amount);
		} catch (InsufficientBalanceException e) {
			e.printStackTrace();
			return 0;
		}
		virtualWalletMapper.updateBalance(walletId, vbo.balance());

		VirtualWalletTransactionPO transaction = new VirtualWalletTransactionPO();

		transaction.setAmount(amount);
		transaction.setWalletId(walletId);
		transaction.setFromWalletId(walletId);
		transaction.setToWalletId(null);
		transaction.setStatus(TransactionStatus.DEBIT);
		int result=transactionMapper.saveTransaction(transaction);
		return result;

	}

	//充值
	@Transactional
	@Override
	public int credit(Integer walletId, BigDecimal amount) {
		VirtualWalletPO wallet = virtualWalletMapper.getVirtualWallet(walletId);
		VirtualWalletBO vbo = new VirtualWalletBO(1);
		vbo.setBalance(wallet.getBalance());
		vbo.setUserId(wallet.getUserId());
		vbo.setWalletId(wallet.getWalletId());
		try {
			vbo.credit(amount);
		} catch (InvalidAmountException e) {
			e.printStackTrace();
			return 0;
		}

		virtualWalletMapper.updateBalance(walletId, vbo.balance());

		VirtualWalletTransactionPO transaction = new VirtualWalletTransactionPO();

		transaction.setAmount(amount);
		transaction.setWalletId(walletId);
		transaction.setFromWalletId(null);
		transaction.setToWalletId(walletId);
		transaction.setStatus(TransactionStatus.CREDIT);
		int result=transactionMapper.saveTransaction(transaction);
		return result;
	}

	//支付
	@Transactional
	@Override
	public int transfer(Integer fromWalletId, Integer toWalletId, BigDecimal amount, Integer orderId) {
		//商家和用户的余额更新+流水记录
		VirtualWalletPO fromwallet = virtualWalletMapper.getVirtualWallet(fromWalletId);
		VirtualWalletBO vboFrom = new VirtualWalletBO(1);
		vboFrom.setBalance(fromwallet.getBalance());
		vboFrom.setUserId(fromwallet.getUserId());
		vboFrom.setWalletId(fromwallet.getWalletId());
		
		BVirtualWalletPO towallet = bvirtualWalletMapper.getVirtualWallet(toWalletId);
		BVirtualWalletBO bvboTo = new BVirtualWalletBO();
		bvboTo.setBalance(towallet.getBalance());
		bvboTo.setBusinessId(towallet.getBusinessId());
		bvboTo.setWalletId(towallet.getWalletId());
		
        int result=0;
		try {
			vboFrom.debit(amount);
		} catch (InsufficientBalanceException e) {
			e.printStackTrace();
            return 0;
		}

		try {
			bvboTo.credit(amount);
		} catch (InvalidAmountException e) {
			e.printStackTrace();
			return 0;
		}

		virtualWalletMapper.updateBalance(fromWalletId, vboFrom.balance());
		bvirtualWalletMapper.updateBalance(toWalletId, bvboTo.getBalance());

		VirtualWalletTransactionPO transaction = new VirtualWalletTransactionPO();
		transaction.setAmount(amount);
		transaction.setWalletId(fromWalletId);
		transaction.setFromWalletId(fromWalletId);
		transaction.setToWalletId(toWalletId);
		transaction.setStatus(TransactionStatus.TRANSFER);
		result=transactionMapper.saveTransaction(transaction);

			//修改订单状态
		result=ordersMapper.updateOrderState(orderId , 1);

		return result;
	}
}
